/**
 * 
 */
package com.huniu.analysis.colony;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.tags.BodyTag;
import org.htmlparser.tags.MetaTag;
import org.htmlparser.tags.TitleTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.htmlparser.util.SimpleNodeIterator;

import com.huniu.analysis.model.HtmlComponents;
import com.huniu.analysis.model.HtmlQuality;
import com.huniu.analysis.model.QualityXMLProperty;
import com.huniu.links.exception.LinkProcessException;
import com.huniu.utility.DateUtil;
import com.huniu.utility.constant.GlobalConstants;

/**
 * @author zandy (chenheng)
 * 
 */
public class ScoutBeeAnalyseImpl extends AbstractBeeAnalyseImpl implements
		IScoutBeeAnalyse {

	private String[] nectarArray;
	private String link;
	private String qualityFolder;

	public void setNectarArray(String[] nectarArray) {
		this.nectarArray = nectarArray;
	}

	public void setLink(String link) {
		this.link = link;
	}

	public void setQualityFolder(String qualityFolder) {
		this.qualityFolder = qualityFolder;
	}

	public void analyse() {
		try {
			HtmlComponents components = parseHtmlComponents(link);
			List<HtmlQuality> qualityList = new ArrayList<HtmlQuality>();
			for (String nectar : nectarArray) {
				HtmlQuality quality = parseHtmlQuality(nectar, components);
				qualityList.add(quality);
			}
			Document document = generateQualityDocument(qualityList);
			generateQualityFile(document);
		} catch (LinkProcessException e) {

		}
	}

	private Document generateQualityDocument(List<HtmlQuality> qualityList) {
		Document qualityDocument = DocumentHelper.createDocument();
		org.dom4j.Element root = qualityDocument
				.addElement(QualityXMLProperty.ROOT);
		Iterator<HtmlQuality> iterator = qualityList.iterator();
		while (iterator.hasNext()) {
			HtmlQuality quality = iterator.next();
			root.addElement(QualityXMLProperty.ELEMENT)
					.addAttribute(QualityXMLProperty.ELEMENT_NECTAR, quality.getDictionary())
					.addAttribute(QualityXMLProperty.ELEMENT_VALUE, String.valueOf(quality.getTotalQuality()))
					.addText(quality.getLink());
		}
		return qualityDocument;
	}
	
	private void generateQualityFile(Document document) throws LinkProcessException {
		String fileName = DateUtil.convertDateToString(new Date(),
				DateUtil.DATE_FORMAT_2);
		String filePath = this.qualityFolder + File.separator + fileName + QualityXMLProperty.EXTENSION;
		try {
			OutputFormat format = OutputFormat.createPrettyPrint();
			XMLWriter writer = new XMLWriter(
					new FileWriter(new File(filePath)), format);
			writer.write(document);
			writer.close();
		} catch (IOException e) {
			throw new LinkProcessException("Write XML document failure", e);
		}
	}

	private HtmlQuality parseHtmlQuality(String nectar,
			HtmlComponents components) {
		HtmlQuality quality = new HtmlQuality();
		quality.setDictionary(nectar);
		quality.setLink(link);
		String regex = "(.*" + nectar + ".*)+";
		Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
		Matcher mather = pattern.matcher(components.getTitle());
		if (mather.find()) {
			quality.setTitleQuality(10);
		}
		return quality;
	}

	private HtmlComponents parseHtmlComponents(String url)
			throws LinkProcessException {
		String html = getCachedContent(link, GlobalConstants.LINK_PAGE_CACHE_NAME);
		Parser parser = Parser.createParser(html, CHARSET);
		NodeFilter nodeFilter = null;
		NodeList nodeList = null;
		SimpleNodeIterator iterator = null;
		HtmlComponents components = new HtmlComponents();
		try {
			// Filter Title Tag
			nodeFilter = new NodeClassFilter(TitleTag.class);
			nodeList = parser.extractAllNodesThatMatch(nodeFilter);
			iterator = nodeList.elements();
			while (iterator.hasMoreNodes()) {
				Node node = iterator.nextNode();
				components.setTitle(node.toHtml());
			}
			// Filter Meta Tag
			nodeFilter = new NodeClassFilter(MetaTag.class);
			nodeList = parser.extractAllNodesThatMatch(nodeFilter);
			iterator = nodeList.elements();
			List<String> metaList = new ArrayList<String>();
			while (iterator.hasMoreNodes()) {
				Node node = iterator.nextNode();
				metaList.add(node.toHtml());
			}
			components.setMetaList(metaList);
			// Filter Body Tag
			nodeFilter = new NodeClassFilter(BodyTag.class);
			nodeList = parser.extractAllNodesThatMatch(nodeFilter);
			iterator = nodeList.elements();
			while (iterator.hasMoreNodes()) {
				Node node = iterator.nextNode();
				components.setBody(node.toHtml());
			}
		} catch (ParserException e) {
			throw new LinkProcessException("Parse htmp page error", e);
		}
		return components;
	}

}
